package com.ds.dsm.manager.view;

import com.ds.config.ErrorResultModel;
import com.ds.config.ResultModel;
import com.ds.context.JDSActionContext;
import com.ds.editor.cmd.ESDChrome;
import com.ds.enums.db.MethodChinaName;
import com.ds.esd.client.ESDFacrory;
import com.ds.esd.client.Project;
import com.ds.esd.custom.CustomViewFactory;
import com.ds.esd.custom.ESDClass;
import com.ds.esd.custom.annotation.CustomAnnotation;
import com.ds.esd.custom.api.annotation.APIEventAnnotation;
import com.ds.esd.custom.api.enums.CustomCallBack;
import com.ds.esd.custom.api.enums.RequestPathEnum;
import com.ds.esd.custom.bean.ApiClassConfig;
import com.ds.esd.custom.bean.MethodConfig;
import com.ds.esd.dsm.DSMFactory;
import com.ds.esd.dsm.aggregation.DomainInst;
import com.ds.esd.dsm.view.ViewInst;
import com.ds.esd.tool.module.EUModule;
import com.ds.esd.tool.ui.enums.ComponentType;
import com.ds.esd.tool.ui.module.ModuleComponent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller
@RequestMapping(path = "/dsm/manager/view/action/")
public class BuildViewMenu {


    @MethodChinaName(cname = "编译")
    @RequestMapping(method = RequestMethod.POST, value = "dsmBuildView")
    @CustomAnnotation(imageClass = "xuicon spafont spa-icon-debug1")
    @APIEventAnnotation(callback = {CustomCallBack.Reload}, customRequestData = RequestPathEnum.treegridrow)
    public @ResponseBody
    ResultModel<Boolean> dsmBuildView(String viewInstId, String domainId, String sourceClassName, String projectName, String methodName) {
        ResultModel<Boolean> result = new ResultModel<Boolean>();
        try {

            Project project = ESDFacrory.getESDClient().getProjectByName(projectName);
            List<ViewInst> viewInsts = new ArrayList<>();
            if (viewInstId != null && !viewInstId.equals("")) {
                viewInsts.add(DSMFactory.getInstance().getViewManager().getViewInstById(viewInstId));
            } else {
                viewInsts = DSMFactory.getInstance().getViewManager().getViewInstList(project.getProjectName(), domainId);
            }

            for (ViewInst viewInst : viewInsts) {
                if (sourceClassName != null) {
                    ApiClassConfig esdClassConfig = DSMFactory.getInstance().getAggregationManager().getApiClassConfig(sourceClassName, domainId);
                    if (methodName != null && !methodName.equals("")) {
                        MethodConfig methodAPIBean = esdClassConfig.getMethodByName(methodName);
                        DSMFactory.getInstance().getViewManager().buildView(methodAPIBean, viewInst.getViewInstId(), getCurrChromeDriver());
                    } else {
                        DSMFactory.getInstance().getViewManager().buildView(esdClassConfig, viewInst.getViewInstId(), getCurrChromeDriver());
                    }

                } else {
                    DSMFactory.getInstance().getViewManager().buildAggView(viewInst, getCurrChromeDriver());
                }

                if (!viewInst.getViewEntityList().contains(sourceClassName)) {
                    viewInst.getViewEntityList().add(sourceClassName);
                    DSMFactory.getInstance().getViewManager().updateViewInst(viewInst, true);
                }

                ESDFacrory.getInstance().dyReload(null);
                getCurrChromeDriver().printLog("编译完成！", true);

            }
        } catch (Exception e) {
            e.printStackTrace();
            result = new ErrorResultModel<>();
            ((ErrorResultModel) result).setErrdes(e.getMessage());
        }
        return result;
    }

    @RequestMapping(value = {"buildView"}, method = {RequestMethod.POST})
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_projectName})
    @CustomAnnotation(index = 1, caption = "编译视图", imageClass = "spafont spa-icon-moveforward")
    @ResponseBody
    public ResultModel<Boolean> buildView(String domainId, String projectName, String viewInstId, String sourceClassName, String methodName) {
        ResultModel resultModel = new ResultModel();
        ESDChrome chrome = getCurrChromeDriver();

        try {
            Project project = ESDFacrory.getESDClient().getProjectByName(projectName);
            List<ViewInst> viewInsts = new ArrayList<>();
            if (viewInstId != null && !viewInstId.equals("")) {
                viewInsts.add(DSMFactory.getInstance().getViewManager().getViewInstById(viewInstId));
            } else {
                viewInsts = DSMFactory.getInstance().getViewManager().getViewInstList(project.getProjectName(), domainId);
            }

            for (ViewInst viewInst : viewInsts) {
                DomainInst domainInst = DSMFactory.getInstance().getAggregationManager().getDomainInstById(domainId);
                List<MethodConfig> allViewConfigs = new ArrayList<>();
                if (sourceClassName != null) {
                    ApiClassConfig esdClassConfig = DSMFactory.getInstance().getAggregationManager().getApiClassConfig(sourceClassName, domainId);
                    if (methodName == null || methodName.equals("")) {
                        allViewConfigs.addAll(esdClassConfig.getAllMethods());
                    } else {
                        MethodConfig methodAPIBean = esdClassConfig.getMethodByName(methodName);
                        allViewConfigs.add(methodAPIBean);
                    }
                } else {
                    List<ESDClass> esdClassList = viewInst.getViewProxyClasses();
                    for (ESDClass esdClass : esdClassList) {
                        ApiClassConfig esdClassConfig = DSMFactory.getInstance().getAggregationManager().getApiClassConfig(esdClass.getSourceClassName(), domainId);
                        if (methodName == null || methodName.equals("")) {
                            allViewConfigs.addAll(esdClassConfig.getAllMethods());
                        } else {
                            MethodConfig methodAPIBean = esdClassConfig.getMethodByName(methodName);
                            allViewConfigs.add(methodAPIBean);
                        }
                    }
                }


                for (MethodConfig methodAPIBean : allViewConfigs) {
                    if (methodAPIBean.isModule()) {
                        EUModule module = ESDFacrory.getESDClient().getModule(methodAPIBean.getUrl(), domainInst.getProjectVersionName());
                        if (module != null) {
                            List<ModuleComponent> moduleComponents = module.getComponent().findComponents(ComponentType.Module, null);
                            for (ModuleComponent moduleComponent : moduleComponents) {
                                if (moduleComponent.getEuModule() != null) {
                                    ESDFacrory.getESDClient().delModule(moduleComponent.getEuModule());
                                }
                            }
                            ESDFacrory.getESDClient().delModule(module);
                        }
                        CustomViewFactory.getInstance().buildView(methodAPIBean, domainInst.getProjectVersionName(), (Map<String, ?>) JDSActionContext.getActionContext().getContext(), true);
                    }
                }

            }


        } catch (Exception e) {
            e.printStackTrace();
            chrome.printError(e.getMessage());
            ((ErrorResultModel) resultModel).setErrdes(e.getMessage());
        }
        return resultModel;
    }

    @RequestMapping(value = {"clear"}, method = {RequestMethod.POST})
    @APIEventAnnotation(customRequestData = {RequestPathEnum.SPA_projectName})
    @CustomAnnotation(index = 3, caption = "重置", imageClass = "spafont spa-icon-resetpath")
    @ResponseBody
    public ResultModel<Boolean> clear(String domainId, String sourceClassName, String methodName) {
        ResultModel resultModel = new ResultModel();
        ESDChrome chrome = getCurrChromeDriver();
        try {
            ApiClassConfig apiClassConfig = DSMFactory.getInstance().getAggregationManager().getApiClassConfig(sourceClassName, domainId);
            List<MethodConfig> configs = new ArrayList<>();
            if (methodName == null || methodName.equals("")) {
                configs = apiClassConfig.getAllProxyMethods();
            } else {
                MethodConfig methodConfig = apiClassConfig.getMethodByName(methodName);
                if (methodConfig != null) {
                    configs.add(methodConfig);
                    configs.addAll(methodConfig.getAllChildViewMethod());
                }
            }

            Set<String> esdClassNames = new HashSet<>();
            esdClassNames.add(sourceClassName);
            for (MethodConfig methodConfig : configs) {
                if (methodConfig.getViewClassName() != null) {
                    esdClassNames.add(methodConfig.getViewClassName());

                }
                if (methodConfig.getView() != null) {
                    Set<Class> classes = methodConfig.getView().getOtherClass();
                    for (Class clazz : classes) {
                        esdClassNames.add(clazz.getName());
                    }
                }
            }


            DSMFactory.getInstance().getAggregationManager().delAggEntity(domainId, esdClassNames);
            DSMFactory.getInstance().getAggregationManager().deleteApiClassConfig(domainId, esdClassNames);
        } catch (Exception e) {
            e.printStackTrace();
            chrome.printError(e.getMessage());
            ((ErrorResultModel) resultModel).setErrdes(e.getMessage());
        }
        return resultModel;
    }

    public ESDChrome getCurrChromeDriver() {
        ESDChrome chrome = JDSActionContext.getActionContext().Par("$currChromeDriver", ESDChrome.class);
        return chrome;
    }


}

